package com.sbxApp.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.common.constants.CloudDiskConstant;
import com.common.utils.MinioUtil;
import com.common.utils.RequestUtil;
import com.sbxApp.entity.CloudDisk;
import com.sbxApp.mapper.CloudDiskMapper;
import com.sbxApp.service.CloudDiskService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;
import java.util.UUID;


@Service
public class CloudDiskServiceImpl implements CloudDiskService {

    @Resource
    private MinioUtil minioUtil;

    @Resource
    private CloudDiskMapper cloudDiskMapper;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void uploadFile(MultipartFile file, String visit, String parentId, String name, String bucket) {

        CloudDisk cloudDisk = new CloudDisk();
        if (!CloudDiskConstant.FileVisit.PUBLIC_FILE.getType().equals(visit) && !CloudDiskConstant.FileVisit.PRIVATE_FILE.getType().equals(visit)) {
            throw new RuntimeException("权限异常！");
        }

        String minioFileId = UUID.randomUUID().toString().replace("-", "");
        cloudDisk

                .setCreator("chenxiaodun")
                .setCreated(new Date())
                .setType(CloudDiskConstant.FilesType.FILE.getType())
                .setOriginName(file.getName()+ file.getContentType())
//                .setOriginName(name)
                .setParentId(parentId)
                .setMinioFileId(minioFileId)
                .setSize(file.getSize())
                .setVisit(visit)
                //.setCreator(user.getUserName())
                .setBucket(bucket);
        try {
            minioUtil.putObject(bucket, minioFileId, file);
        } catch (Exception e) {
            e.printStackTrace();
        }
        cloudDiskMapper.insert(cloudDisk);


    }

    @Override
    public void downFile(String id, HttpServletResponse response) {
        CloudDisk cloudDisk = cloudDiskMapper.selectById(id);

        InputStream file = minioUtil.getObject(cloudDisk.getBucket(), cloudDisk.getMinioFileId());
        try {
            response.setContentType("application/x-download");
            // 文件名中文乱码处理
            response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(cloudDisk.getOriginName(), "utf-8"));
            byte[] buff = new byte[1024];
            try (BufferedInputStream bis = new BufferedInputStream(file);
                 OutputStream outputStream = response.getOutputStream()) {
                response.addHeader("content-length", bis.available() + "");
                int read = bis.read(buff);
                while (read != -1) {
                    outputStream.write(buff, 0, buff.length);
                    outputStream.flush();
                    read = bis.read(buff);
                }
                outputStream.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (Exception ex) {
            ex.printStackTrace();

        }


    }

    @Override
    public void createDir(CloudDisk cloudDisk) {
        String loginUserId = RequestUtil.getLoginUserId();
        String loginUserName = RequestUtil.getLoginUserName();
        if (StringUtils.isEmpty(cloudDisk.getVisit())) {
            cloudDisk.setVisit("public");
        } else if (!"public".equals(cloudDisk.getVisit()) && !"private".equals(cloudDisk.getVisit())) {
            throw new RuntimeException("权限异常！");
        }
        if (!loginUserId.equals(cloudDisk.getParentId())) {//判断parentId是否为当前用户id
            LambdaQueryWrapper<CloudDisk> fileOBLambdaQueryWrapper = new LambdaQueryWrapper<>();
            fileOBLambdaQueryWrapper.eq(CloudDisk::getId, cloudDisk.getParentId());
            List<CloudDisk> cloudDisks = cloudDiskMapper.selectList(fileOBLambdaQueryWrapper);
            Assert.isTrue(!CollectionUtils.isEmpty(cloudDisks), "此文件夹已不存在，无法创建子文件夹!");
        }
        cloudDisk.setCreator(loginUserName).setCreated(new Date());
        cloudDiskMapper.updateById(cloudDisk);
    }

    @Override
    public void putFileOrDir(String id, String name, String visit) {
        CloudDisk cloudDisk = cloudDiskMapper.selectById(id);
        Assert.notNull(cloudDisk, "文件/文件夹不存在!");
        if (!StringUtils.isEmpty(visit)) {
            if (!"public".equals(visit) && !"private".equals(visit)) {
                throw new RuntimeException("权限取值范围异常！"+ visit);
            }
        }

        cloudDisk.setOriginName(name);
        cloudDisk.setVisit(visit);
        cloudDiskMapper.updateById(cloudDisk);
    }

    @Override
    public void delFileOrDir(String id) {
        CloudDisk cloudDisk = cloudDiskMapper.selectById(id);
        if (cloudDisk == null) {
            return;
        }
        delFileOrDir(cloudDisk);
    }

    public void delFileOrDir(CloudDisk cloudDisk) {
        if (!CloudDiskConstant.FilesType.DIR.getType().equalsIgnoreCase(cloudDisk.getType())) {
            minioUtil.delObject(cloudDisk.getBucket(), cloudDisk.getMinioFileId());
            cloudDiskMapper.deleteById(cloudDisk.getId());
            return;
        }
        cloudDiskMapper.deleteById(cloudDisk.getId());
        LambdaQueryWrapper<CloudDisk> fileOBLambdaQueryWrapper = new LambdaQueryWrapper<>();
        fileOBLambdaQueryWrapper.eq(CloudDisk::getParentId, cloudDisk.getId());
        List<CloudDisk> cloudDisks = cloudDiskMapper.selectList(fileOBLambdaQueryWrapper);
        if (CollectionUtils.isEmpty(cloudDisks)) {
            return;
        }
        for (CloudDisk ob : cloudDisks) {
            delFileOrDir(ob);
        }
    }

    @Override
    public void cpFile() {

    }

    @Override
    public Page<CloudDisk> fileList(String id, Boolean self, Integer pageIndex, Integer pageSize) {
        Page<CloudDisk> page = new Page<>(pageIndex, pageSize);
        LambdaQueryWrapper<CloudDisk> wrapper = new LambdaQueryWrapper<CloudDisk>();

        wrapper.eq(Boolean.FALSE.equals(self), CloudDisk::getId, id)
                .eq(Boolean.TRUE.equals(self), CloudDisk::getParentId, id);


        page = cloudDiskMapper.selectPage(page, wrapper);
        List<CloudDisk> cloudDisks = page.getRecords();
        for (CloudDisk cloudDisk : cloudDisks) {
            fileList(cloudDisk);
        }


        page.setRecords(cloudDisks);


        return page;
    }

    private void fileList(CloudDisk cloudDisk) {
        if (cloudDisk == null || !CloudDiskConstant.FilesType.DIR.getType().equalsIgnoreCase(cloudDisk.getType())) {
            return;
        }
        LambdaQueryWrapper<CloudDisk> fileOBLambdaQueryWrapper = new LambdaQueryWrapper<>();
        fileOBLambdaQueryWrapper.eq(CloudDisk::getParentId, cloudDisk.getId());
        List<CloudDisk> cloudDisks = cloudDiskMapper.selectList(fileOBLambdaQueryWrapper);
        cloudDisk.setChildren(cloudDisks);
        if (!CollectionUtils.isEmpty(cloudDisks)) {
            for (CloudDisk ob : cloudDisks) {
                fileList(ob);
            }
        }
    }
}
